﻿Public Class IOPortActiveForm
    Private _pi As ProjectItem

    '选择设备的网络地址
    Private _netID As Byte = 0
    Private _portNo As Integer = 0
    '起始地址
    Private _offset As UShort = 2066
    Private _offsetEx16 As UShort = 2068
    Private buf() As UShort
    '选择的冷库编号
    Private _refID As UShort = 0
    Private buf1() As UShort

    '正在修改参数标志
    Private _isModify As Boolean = False

    Private Sub IOPortActiveForm_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If Me._isModify Then
            Me.ExitModify()
        End If
        MyBase.OnClosing(e)
    End Sub

    Private Sub LoadAllRef()
        Dim tn As TreeNode
        Dim tn1 As TreeNode

        Dim dts As New DevTypeService(_pi)
        Dim rts As New RefTypeService(_pi)


        For Each dti As DevTypeItem In dts.GeDevGroupList()   '设备列表

            For Each rti As RefTypeItem In rts.GeRefGroupList(dti.NetId) '增加该设备冷库信息

                tn = Me.TreeView1.Nodes.Add(rti.RefName)
                tn.Tag = rti

                Dim ais As New AiPortTypeService(rti)

                For Each ai As AiPortTypeItem In ais.GetAiGroupList()

                    tn1 = tn.Nodes.Add(ai.PortName)
                    tn1.Tag = ai

                Next
            Next
        Next

        Me.TreeView1.ExpandAll()

    End Sub


    Private Sub IOPortActiveForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        _pi = MainForm.pi


        Me.HideAllControl()

        LoadAllRef()

    End Sub
    Private Sub ClearData()
        For Each ctl As Control In Me.ActivePanel.Controls
            If ctl.GetType Is GetType(RadioButton) Then
                CType(ctl, RadioButton).Checked = False
            End If
        Next

    End Sub

    '隐藏/显示Panel中的所有控件
    Private Sub HideAllControl()
        For Each ctl As Control In Me.RevisePanel.Controls
            ctl.Visible = False
            If ctl.GetType Is GetType(RadioButton) Then
                CType(ctl, RadioButton).Enabled = False
            End If
        Next

        ' Me.GroupBox1.Visible = False
        Me.btnModify.Enabled = False
        Me.btnOK.Enabled = False
        Me.lbl_tip.Visible = True
        Me.lblSelected.Text = ""
    End Sub

    ''' <summary>
    ''' 保存数据
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        Dim result As Boolean = False
        Me.Cursor = Cursors.WaitCursor
        TreeView1.Enabled = False
        Me.btnOK.Enabled = False
        Me.btnCancel.Enabled = False
        Me.RevisePanel.Enabled = False
        Me._isSaving = True
        result = Save()
        Me._isSaving = False
        Me.btnOK.Enabled = True
        Me.btnCancel.Enabled = True
        Me.RevisePanel.Enabled = True

        Me.Cursor = Cursors.Default

        If result Then
            EnableModify(False)
            msg.Show("参数保存成功")
            
            RefreshData(_portNo) '重新读取数据

        Else
            msg.ShowError("参数保存失败")
        End If
        TreeView1.Enabled = True
    End Sub
    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        Me.Close()
    End Sub

    Private Sub btnModify_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnModify.Click
        Me.btnModify.Enabled = False
        If EnterModify() = False Then
            msg.Show("无法修改参数请重试")
            Me.btnModify.Enabled = True
            Exit Sub
        End If

        EnableModify(True)

    End Sub

    Private Sub EnableModify(ByVal value As Boolean)

        Me.btnModify.Enabled = Not value
        Me.btnOK.Enabled = value

        For Each ctl As Control In Me.ActivePanel.Controls

            If ctl.GetType Is GetType(RadioButton) Then
                CType(ctl, RadioButton).Enabled = value
            End If
        Next

        For Each ctl As Control In Me.Panel1.Controls

            If ctl.GetType Is GetType(RadioButton) Then
                CType(ctl, RadioButton).Enabled = value
            End If
        Next

    End Sub

    ''' <summary>
    ''' 保存所有参数
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function Save() As Boolean

        Dim value As UShort

        Select Case CInt(lbltitle.Tag)   '显示激活设置
            Case 0
                If Me.rb_inactive.Checked = True Then   '设置为未激活

                    If _portNo > 16 Then

                        value = (1 << (_portNo - 17)) Or SetShort(buf(2), (_portNo - 17))

                        If Not Save(2, value) Then '设置为未激活
                            Return False
                        End If


                    Else

                        value = (1 << (_portNo - 1)) Or SetShort(buf(0), (_portNo - 1))

                        If Not Save(0, value) Then '设置为未激活
                            Return False
                        End If


                    End If


                End If

            Case 1
                If Me.rb_active.Checked = True Then   '设置为激活

                    If _portNo > 16 Then

                        value = (0 << (_portNo - 17)) Or SetShort(buf(2), (_portNo - 17))

                        If Not Save(2, value) Then '设置为激活
                            Return False
                        End If


                    Else

                        value = (0 << (_portNo - 1)) Or SetShort(buf(0), (_portNo - 1))

                        If Not Save(0, value) Then '设置为激活
                            Return False
                        End If


                    End If



                End If

        End Select

        Select Case CInt(Alarmlbltitle.Tag)   '报警激活设置
            Case 0
                If Me.Alarmrb_inactive.Checked = True Then   '设置为未激活

                    If _portNo > 16 Then

                        value = (1 << (_portNo - 17)) Or SetShort(buf(3), (_portNo - 17))

                        If Not Save(3, value) Then '设置为未激活
                            Return False
                        End If


                    Else

                        value = (1 << (_portNo - 1)) Or SetShort(buf(1), (_portNo - 1))

                        If Not Save(1, value) Then '设置为未激活
                            Return False
                        End If


                    End If


                End If



            Case 1
                If Me.Alarmrb_active.Checked = True Then   '设置为激活

                    If _portNo > 16 Then

                        value = (0 << (_portNo - 17)) Or SetShort(buf(3), (_portNo - 17))

                        If Not Save(3, value) Then '设置为激活
                            Return False
                        End If


                    Else

                        value = (0 << (_portNo - 1)) Or SetShort(buf(1), (_portNo - 1))

                        If Not Save(1, value) Then '设置为激活
                            Return False
                        End If


                    End If



                End If

        End Select



        '设置修改使能变量
        If ParameterModifyClass.SetModifyConfirm(_netID) = False Then
            Return False
        End If



        '修改门变量
        If ExitModify() = False Then
            Debug.Write("ExitModify错误")
        End If

        Return True

    End Function

    ''' <summary>
    ''' 保存参数
    ''' </summary>
    ''' <param name="index"></param>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function save(ByVal index As UShort, ByVal value As UShort) As Boolean
        Dim offset As UShort = _offset + index + 1000
        Return COMHelper.Instance.Write(_netID, FunctionCode.WordWrite, offset, value)
    End Function
   
    ''' <summary>
    ''' 进入修改
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function EnterModify() As Boolean
        If g_test Then
            _isModify = True
            Return True
        End If

        _isModify = True

        Dim result As Boolean
        result = ParameterModifyClass.EnterModify(_netID)

        If result = False Then
            _isModify = False
            Return False
        End If

        '开始发送心跳包
        Me.TimerHeart.Start()

        Return True
    End Function


    ''' <summary>
    ''' 退出修改
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ExitModify() As Boolean
        '门变量置为1
        Dim result As Boolean
        result = ParameterModifyClass.ExitModify(_netID)

        '停止发送心跳包
        Me.TimerHeart.Stop()

        If result = True Then  '修改门变量成功
            _isModify = False
        End If

        Return True
    End Function


#Region "发送心跳包"

    '心跳包连续发送错误的次数
    Private _heartFailCount As Integer = 0

    '心跳值
    Private _heartValue As Short = 0

    '心跳值是否初始化
    Private _bheartValue As Boolean = False

    '是否正在发送心跳标志
    Private _heartSending As Boolean = False

    '是否正在保存标志
    Public _isSaving As Boolean = False

    '心跳包地址
    Private _heartIncreamentAddress As UShort = 7063
    '心跳参数ID为选择ID
    Private netid As Byte

    ''' <summary>
    ''' 发送心跳包
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub HeartSend()
        If _bheartValue = False Then
            Dim b() As Short
            netid = _netID
            b = COMHelper.Instance.Send4Short(netid, FunctionCode.WordWritableRead, _heartIncreamentAddress, 1)
            If b IsNot Nothing AndAlso b.Length = 1 Then
                _heartValue = b(0)
                _bheartValue = True
            Else
                Exit Sub
            End If
        End If

        _heartValue = (_heartValue + 1) Mod UShort.MaxValue

        Dim result As Boolean
        result = COMHelper.Instance.Write(netid, FunctionCode.WordWrite, _heartIncreamentAddress, _heartValue)

        If result Then
            _heartFailCount = 0
        Else
            _heartFailCount += 1
        End If

        If _heartFailCount > 10 Then
            '提示用户可能断开连接了.
        End If

    End Sub

    ''' <summary>
    ''' 心跳定时器Tick事件
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub TimerHeart_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerHeart.Tick
        If Not g_HeartSend Then
            Exit Sub
        End If

        If _heartSending OrElse _isSaving Then
            Exit Sub
        End If

        _heartSending = True
        Me.HeartSend()
        _heartSending = False
    End Sub

#End Region

    Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)
        If Me._isModify Then
            Me.ExitModify()
        End If
        MyBase.OnClosing(e)
    End Sub

    Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
        Dim tn As TreeNode
        Me.lbl_tip.Visible = False
        Dim ai As AiPortTypeItem
        Dim result As Boolean

        tn = Me.TreeView1.SelectedNode

        If tn Is Nothing Then
            Exit Sub
        End If

        If TypeOf tn.Tag Is RefTypeItem Then
            Exit Sub
        End If


        If TypeOf tn.Tag Is AiPortTypeItem Then

            TreeView1.Enabled = False


            ai = CType(tn.Tag, AiPortTypeItem)

            '显示选择设备的名称
            Me.lblSelected.Text = tn.Text

            '关闭设备选择提示
            lbl_tip.Visible = False

            Me.lbl_tip.Visible = False

            '禁止点击"修改"按钮前修改参数
            Me.btnModify.Enabled = False
            Me.btnOK.Enabled = False

            _netID = ai.NetId   '保存当前选择的设备号

            _portNo = ai.PortNo

            For Each ctl As Control In Me.RevisePanel.Controls
                ctl.Visible = True
            Next

            Me.GroupBox1.Visible = True

            If Me._isModify Then
                Me.ExitModify()
            End If

            EnableModify(False)
           
            result = RefreshData(ai.PortNo)

           


            If result = False Then
                Me.btnModify.Enabled = False

            Else

                Me.btnModify.Enabled = True
            End If
            TreeView1.Enabled = True

        End If

    End Sub


    ''' <summary>
    ''' 刷新AI原点修正数据
    ''' </summary>
    ''' <remarks></remarks>
    Private Function RefreshData(ByVal portNo As Integer) As Boolean
        Me.Cursor = Cursors.WaitCursor
        Try
            buf = COMHelper.Instance.Send4UShort(_netID, FunctionCode.WordWritableRead, _offset, 4)
        Catch ex As Exception
            Debug.WriteLine(ex.Message)
        Finally
            Me.Cursor = Cursors.Default
        End Try

        If buf Is Nothing Then
            Me.btnModify.Enabled = False

            msg.ShowError("读取参数失败")
            Return False
        End If

        '解析端口激活数据
        If _portNo > 16 Then  '湿度端口状态
            If GetShort(buf(2), (_portNo - 17)) = 0 Then    '显示激活状态
                rb_active.Checked = True
                rb_inactive.Checked = False
                lbltitle.Tag = 0
            Else

                rb_active.Checked = False
                rb_inactive.Checked = True
                lbltitle.Tag = 1

            End If

            If GetShort(buf(3), (_portNo - 17)) = 0 Then   '报警激活状态

                Alarmrb_active.Checked = True
                Alarmrb_inactive.Checked = False
                Alarmlbltitle.Tag = 0
            Else

                Alarmrb_active.Checked = False
                Alarmrb_inactive.Checked = True
                Alarmlbltitle.Tag = 1

            End If


        Else   '温度端口状态

            If GetShort(buf(0), (_portNo - 1)) = 0 Then    '显示激活状态
                rb_active.Checked = True
                rb_inactive.Checked = False
                lbltitle.Tag = 0
            Else

                rb_active.Checked = False
                rb_inactive.Checked = True
                lbltitle.Tag = 1

            End If

            If GetShort(buf(1), (_portNo - 1)) = 0 Then   '报警激活状态
                Alarmrb_active.Checked = True
                Alarmrb_inactive.Checked = False
                Alarmlbltitle.Tag = 0
            Else

                Alarmrb_active.Checked = False
                Alarmrb_inactive.Checked = True
                Alarmlbltitle.Tag = 1

            End If


        End If

        Me.btnModify.Enabled = True



        Return True

    End Function

    ''' <summary>
    ''' 判断指定位是否为1
    ''' </summary>
    ''' <param name="b"></param>
    ''' <param name="i"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Shared Function GetShort(ByVal b As UShort, ByVal i As Integer) As UShort
        Dim iTest As UShort
        iTest = 2 ^ i

        Dim result As UShort
        result = b And iTest

        If result > 0 Then
            result = 1
        End If

        Return result
    End Function
    ''' <summary>
    ''' 判断指定位是否0
    ''' </summary>
    ''' <param name="b"></param>
    ''' <param name="i"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Shared Function SetShort(ByVal b As UShort, ByVal i As Integer) As UShort
        Dim iTest As UShort
        iTest = 2 ^ i

        Dim result As UShort
        result = b And (Not iTest)

        'If result > 0 Then
        '    result = 1
        'End If

        Return result
    End Function

    Public Sub New()

        ' 此调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        ' 在 InitializeComponent() 调用之后添加任何初始化。

    End Sub
   
End Class